package com.yfqy.app.modules.order.serviceimpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yfqy.app.concurrency.StockService;
import com.yfqy.app.configure.Idgenerator.SnowflakeIdGenerator;
import com.yfqy.app.constant.GeneralConstants;
import com.yfqy.app.constant.RedisKeyConstants;
import com.yfqy.app.constant.SystemConfigConstants;
import com.yfqy.app.domain.entity.IntegralRecord;
import com.yfqy.app.domain.entity.OrderInfo;
import com.yfqy.app.domain.entity.OrderRefund;
import com.yfqy.app.domain.mapper.CustomerMapper;
import com.yfqy.app.domain.mapper.IntegralRecordMapper;
import com.yfqy.app.domain.mapper.OrderAddressMapper;
import com.yfqy.app.domain.mapper.OrderDeliveryInfoMapper;
import com.yfqy.app.domain.mapper.OrderInfoMapper;
import com.yfqy.app.domain.mapper.OrderItemMapper;
import com.yfqy.app.domain.mapper.OrderRefundMapper;
import com.yfqy.app.domain.mapper.ProductSkuMapper;
import com.yfqy.app.domain.mapper.PromotionProductMapper;
import com.yfqy.app.domain.vo.ResultVO;
import com.yfqy.app.enums.CancelType;
import com.yfqy.app.enums.ErrorCode;
import com.yfqy.app.enums.IntegralType;
import com.yfqy.app.enums.OrderStatus;
import com.yfqy.app.enums.OrderType;
import com.yfqy.app.enums.RefundReason;
import com.yfqy.app.enums.RefundStatus;
import com.yfqy.app.enums.RefundType;
import com.yfqy.app.exception.BusinessException;
import com.yfqy.app.modules.order.context.OrderCancelContext;
import com.yfqy.app.modules.order.director.AbstractOrderCreateBuilderDirector;
import com.yfqy.app.modules.order.dto.OrderAmountDTO;
import com.yfqy.app.modules.order.dto.OrderCreateRequest;
import com.yfqy.app.modules.order.dto.OrderExtendDTO;
import com.yfqy.app.modules.order.dto.OrderInfoDTO;
import com.yfqy.app.modules.order.dto.OrderItemDTO;
import com.yfqy.app.modules.order.dto.OrderQueryDTO;
import com.yfqy.app.modules.order.factory.OrderCreateBuilderFactory;
import com.yfqy.app.modules.order.service.OrderService;
import com.yfqy.app.modules.order.vo.OrderAddressVO;
import com.yfqy.app.modules.order.vo.OrderCreateResultVO;
import com.yfqy.app.modules.order.vo.OrderDeliveryInfoVO;
import com.yfqy.app.modules.order.vo.OrderInfoVO;
import com.yfqy.app.modules.order.vo.OrderItemVO;
import com.yfqy.app.modules.system.dto.DeductionDTO;
import com.yfqy.app.modules.system.service.SystemConfigService;
import com.yfqy.app.modules.wechat.model.WechatRefundRequest;
import com.yfqy.app.modules.wechat.model.WechatRefundResponse;
import com.yfqy.app.modules.wechat.service.WechatPayService;
import com.yfqy.app.modules.wechat.util.WechatPayUtil;
import com.yfqy.app.service.UserService;
import com.yfqy.app.util.AuthUserContext;
import com.yfqy.app.util.JSON;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl extends UserService implements OrderService {

    @Resource
    private OrderInfoMapper orderInfoMapper;
    @Resource
    private OrderItemMapper orderItemMapper;
    @Resource
    private OrderDeliveryInfoMapper orderDeliveryInfoMapper;
    @Resource
    private OrderAddressMapper orderAddressMapper;
    @Resource
    private OrderCreateBuilderFactory orderCreateBuilderFactory;
    @Resource(name = "singleRedisClient")
    private RedissonClient redissonClient;
    @Resource
    private SystemConfigService systemConfigService;
    @Resource
    private CustomerMapper customerMapper;
    @Resource
    private IntegralRecordMapper integralRecordMapper;
    @Resource
    private SnowflakeIdGenerator idGenerator;
    @Resource
    private ProductSkuMapper productSkuMapper;
    @Resource
    private PromotionProductMapper promotionProductMapper;
    @Resource
    private StockService stockService;
    @Resource
    private OrderRefundMapper orderRefundMapper;
    @Resource
    private WechatPayService wechatPayService;
    @Resource(name = "defaultThreadPoolExecutor")
    private ThreadPoolExecutor threadPoolExecutor;

    @Override
    public OrderCreateResultVO createOrder(OrderCreateRequest request) {
        long start = System.currentTimeMillis();
        AbstractOrderCreateBuilderDirector director = orderCreateBuilderFactory.getService(OrderType.of(request.getOrderType()));
        // 1、验证参数
        director.validRequiredParam(request);
        // 2、计算订单金额
        OrderAmountDTO amountDTO = director.calculateAmount(request);
        // 3、在事务中执行订单的创建流程
        OrderInfoDTO orderInfoDTO = director.createOrder(request, amountDTO);
        // 4、添加订单创建成功后的其他任务
        director.afterOrderCreated(
                amountDTO.getPoints(),
                request.getUserId(),
                orderInfoDTO.getId(),
                orderInfoDTO.getPayExpireTime()
        );
        log.info("下单耗时：{}毫秒，orderId：{}", System.currentTimeMillis() - start, orderInfoDTO.getId());
        return OrderCreateResultVO.success(orderInfoDTO);
    }


    /**
     * 管理后台-订单详情接口
     *
     * @param id
     * @return
     */
    @Override
    public OrderInfoVO detail(Long id) {
        OrderInfoVO orderInfoVO = orderInfoMapper.selectOrderInfoVoById(id);
        if (orderInfoVO == null) {
            throw new IllegalArgumentException("订单不存在");
        }
        // 订单商品
        List<OrderItemVO> orderItemVOS = orderItemMapper.selectOrderItemsByOrderId(id);
        orderInfoVO.setItemVOS(orderItemVOS);
        // 订单物流信息
        OrderDeliveryInfoVO orderDeliveryInfoVO = orderDeliveryInfoMapper.selectOrderDeliveryInfoByOrderId(id);
        orderInfoVO.setOrderDeliveryInfoVO(orderDeliveryInfoVO);
        // 订单收货地址
        OrderAddressVO orderAddressVO = orderAddressMapper.selectOrderAddrByOrderId(id);
        orderInfoVO.setOrderAddressVO(orderAddressVO);
        return orderInfoVO;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public ResultVO<Void> cancel(Long orderId) {
        OrderCancelContext context = OrderCancelContext.builder()
                .orderId(orderId)
                .userId(getUserId())
                .cancelType(CancelType.USER_CANCEL)
                .build();
        RLock orderStatusLock = redissonClient.getLock(RedisKeyConstants.ORDER_STATUS_LOCK + context.getOrderId());

        try {
            // 1. 获取分布式锁
            boolean lockAcquired = acquireLock(orderStatusLock);
            if (!lockAcquired) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }

            try {
                // 2. 验证订单状态
                OrderInfoDTO orderInfoDTO = validateOrderForCancellation(context);
                context.setOrderInfoDTO(orderInfoDTO);

                // 3. 执行取消操作
                executeOrderCancellation(context);

                return ResultVO.success();

            } finally {
                // 确保锁释放
                releaseLock(orderStatusLock);
            }

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("取消订单系统错误: orderId={}", context.getOrderId(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR.getCode(), "取消订单失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO<Void> applyRefund(Long orderId) {
        OrderCancelContext context = OrderCancelContext.builder()
                .orderId(orderId)
                .userId(getUserId())
                .cancelType(CancelType.USER_CANCEL)
                .build();
        RLock orderStatusLock = redissonClient.getLock(RedisKeyConstants.ORDER_STATUS_LOCK + context.getOrderId());

        try {
            // 1. 获取分布式锁（带超时时间）
            boolean lockAcquired = acquireLock(orderStatusLock);
            if (!lockAcquired) {
                log.warn("获取订单状态锁失败, orderId: {}", context.getOrderId());
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }

            try {
                // 2. 验证并准备数据
                validateAndPrepareRefundData(context);

                // 3. 创建退款记录（初始状态为处理中）
                OrderRefund orderRefund = createOrderRefund(context);
                orderRefundMapper.insert(orderRefund);

                // 4. 执行订单退款状态更新（数据库操作）
                executeOrderRefund(context);

                // 5. 异步调用微信退款
                asyncProcessWechatRefund(orderRefund);
                return ResultVO.success();

            } finally {
                releaseLock(orderStatusLock);
            }
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("取消订单系统错误: orderId={}", context.getOrderId(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR.getCode(), "取消订单失败");
        }
    }

    private void asyncProcessWechatRefund(OrderRefund orderRefund) {
        TransactionSynchronizationManager.registerSynchronization(
                new TransactionSynchronization() {
                    @Override
                    public void afterCommit() {
                        // 5. 调用微信退款（放在事务外，避免长事务）
                        threadPoolExecutor.execute(
                                () -> processWechatRefund(orderRefund)
                        );
                    }
                }
        );
    }

    /**
     * 验证并准备退款数据
     */
    private void validateAndPrepareRefundData(OrderCancelContext context) {
        OrderInfoDTO orderInfoDTO = orderInfoMapper.selectOrderInfoDTOById(context.getOrderId());
        if (orderInfoDTO == null) {
            throw new BusinessException(ErrorCode.ORDER_NOT_EXIST);
        }
        if (!Objects.equals(context.getUserId(), orderInfoDTO.getUserId())) {
            throw new BusinessException(ErrorCode.NO_OPERATOR_AUTH.getCode(), "申请退款需要本人操作");
        }
        if (!Objects.equals(orderInfoDTO.getOrderStatus(), OrderStatus.PAID.getStatus())) {
            throw new BusinessException(ErrorCode.ORDER_STATUS_CHANGED);
        }
        List<OrderItemDTO> orderItemDTOS = orderItemMapper.selectOrderItemDTOsByOrderId(context.getOrderId());
        orderInfoDTO.setOrderItems(orderItemDTOS);
        context.setOrderInfoDTO(orderInfoDTO);
    }


    /**
     * 处理微信退款（异步或事务外处理）
     */
    public void processWechatRefund(OrderRefund orderRefund) {
        try {
            WechatRefundResponse response = callWechatRefund(orderRefund);
            if (WechatPayUtil.isRefundSuccess(response)) {
                // 更新退款状态为成功
                orderRefundMapper.updateRefundSuccess(orderRefund.getId());
                log.info("微信退款成功, refundId: {}, refundNo: {}", orderRefund.getId(), orderRefund.getRefundNo());
            } else {
                // 更新退款状态为失败
                String errorMsg = response != null ?
                        response.getErrCode() + ":" + response.getErrCodeDes() : "微信退款调用失败";
                orderRefundMapper.updateRefundFailed(orderRefund.getId(),
                        RefundStatus.FAILED.getStatus(),
                        errorMsg);
                log.warn("微信退款失败, refundId: {}, error: {}", orderRefund.getId(), errorMsg);

                // 可以触发告警或重试机制
                //alertRefundFailure(orderRefund, errorMsg);
            }
        } catch (Exception e) {
            log.error("处理微信退款异常, refundId: {}", orderRefund.getId(), e);
            orderRefundMapper.updateRefundFailed(orderRefund.getId(),
                    RefundStatus.FAILED.getStatus(),
                    "系统异常: " + e.getMessage());
        }
    }


    @Override
    public PageInfo<OrderInfoVO> getOrders(OrderQueryDTO orderQueryDTO) {
        try {
            PageHelper.startPage(orderQueryDTO.getPageIndex(), orderQueryDTO.getPageSize());
            orderQueryDTO.setUserId(AuthUserContext.getUserId());
            List<OrderInfoVO> orderInfoVOS = orderInfoMapper.selectByOrderQueryDTO(orderQueryDTO);
            if (CollUtil.isEmpty(orderInfoVOS)) {
                return new PageInfo<>(Collections.emptyList());
            }
            return new PageInfo<>(orderInfoVOS);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        } finally {
            PageHelper.clearPage();
        }
    }


    /**
     * 调用微信退款接口
     */
    private WechatRefundResponse callWechatRefund(OrderRefund orderRefund) {
        WechatRefundRequest request = new WechatRefundRequest();
        request.setTotalFee(orderRefund.getApplyRefundAmount().multiply(BigDecimal.valueOf(100)).intValue());
        request.setRefundFee(request.getTotalFee());
        request.setOutTradeNo(orderRefund.getOrderNo());
        request.setOutRefundNo(orderRefund.getRefundNo());

        return wechatPayService.refund(request);
    }


    /**
     * 验证订单是否可以取消
     */
    private OrderInfoDTO validateOrderForCancellation(OrderCancelContext context) {
        OrderInfoDTO orderInfoDTO = orderInfoMapper.selectOrderInfoDTOById(context.getOrderId());
        if (orderInfoDTO == null) {
            throw new BusinessException(ErrorCode.ORDER_NOT_EXIST);
        }

        if (context.getCancelType() == CancelType.USER_CANCEL) {
            if (!Objects.equals(orderInfoDTO.getUserId(), context.getUserId())) {
                throw new BusinessException(ErrorCode.NO_OPERATOR_AUTH.getCode(), "取消订单需要本人操作");
            }
        }

        if (!OrderStatus.PENDING_PAYMENT.getStatus().equals(orderInfoDTO.getOrderStatus())) {
            log.warn("订单已不是待支付状态不可以取消: orderId={}, status={}", orderInfoDTO.getId(), orderInfoDTO.getOrderStatus());
            throw new BusinessException(ErrorCode.ORDER_STATUS_CANNOT_CANCEL);
        }

        List<OrderItemDTO> orderItemDTOS = orderItemMapper.selectOrderItemDTOsByOrderId(context.getOrderId());
        orderInfoDTO.setOrderItems(orderItemDTOS);

        return orderInfoDTO;
    }

    /**
     * 执行订单取消操作
     */
    private void executeOrderCancellation(OrderCancelContext context) {
        OrderInfoDTO orderInfoDTO = context.getOrderInfoDTO();
        // 1. 更新订单状态
        updateOrderStatus(orderInfoDTO.getId(),
                orderInfoDTO.getOrderStatus(),
                OrderStatus.CANCELLED.getStatus(),
                context.getCancelType());

        // 2. 退回用户积分
        returnUserPointsAndAddIntegralRecord(orderInfoDTO);

        // 3. 释放库存
        releaseInventory(orderInfoDTO);

        log.info("订单取消成功: orderId={}, userId={}", orderInfoDTO.getId(), orderInfoDTO.getUserId());
    }


    /**
     * 执行订单取消操作
     */
    private void executeOrderRefund(OrderCancelContext context) {
        OrderInfoDTO orderInfoDTO = context.getOrderInfoDTO();
        // 1. 更新订单状态
        updateOrderStatus(orderInfoDTO.getId(),
                orderInfoDTO.getOrderStatus(),
                OrderStatus.ALL_REFUNDED.getStatus(),
                context.getCancelType());

        // 2. 退回用户积分
        returnUserPointsAndAddIntegralRecord(orderInfoDTO);

        // 3. 释放库存
        releaseInventory(orderInfoDTO);

        log.info("订单取消成功: orderId={}, userId={}", orderInfoDTO.getId(), orderInfoDTO.getUserId());
    }


    /**
     * 更新订单状态
     *
     * @param orderId      id
     * @param currStatus   订单当前状态
     * @param targetStatus 订单目标状态
     * @param cancelType   取消原因
     */
    private void updateOrderStatus(Long orderId, Byte currStatus, Byte targetStatus, CancelType cancelType) {
        OrderInfo updateOrder = new OrderInfo();
        updateOrder.setId(orderId);
        updateOrder.setOrderStatus(targetStatus);
        updateOrder.setCancelType(cancelType.getType());
        OrderExtendDTO orderExtendDTO = new OrderExtendDTO();
        orderExtendDTO.setBeforeStatus(currStatus);
        updateOrder.setExtend(JSON.stringify(orderExtendDTO));
        if (cancelType == CancelType.MANAGER_CANCEL) {
            updateOrder.setCancelReason("管理员取消了用户订单，取消原因：用户占用库存");
        }
        int updated = orderInfoMapper.cancelOrder(updateOrder, currStatus);
        if (updated == 0) {
            throw new BusinessException(ErrorCode.DB_OPERATION_ERROR.getCode(), "取消订单失败");
        }
    }

    /**
     * 退回用户积分&&添加用户积分变更记录
     */
    private void returnUserPointsAndAddIntegralRecord(OrderInfoDTO orderInfoDTO) {
        try {
            BigDecimal pointAmount = orderInfoDTO.getPointAmount();
            if (pointAmount == null || pointAmount.compareTo(BigDecimal.ZERO) <= 0) {
                log.debug("订单未使用积分，无需退回: orderId={}", orderInfoDTO.getId());
                return;
            }

            log.info("开始退回用户积分: orderId={}", orderInfoDTO.getId());

            // 获取积分抵扣规则
            int pointsToReturn = calculatePointsToReturn(pointAmount);
            Long userId = orderInfoDTO.getUserId();

            // 退回积分
            returnPointsToUser(userId, pointsToReturn);

            // 记录积分变更
            recordIntegralChange(userId, pointsToReturn, orderInfoDTO.getId());

            log.info("退回用户积分完成: userId={}, points={}, orderId={}",
                    userId, pointsToReturn, orderInfoDTO.getId());

        } catch (Exception e) {
            log.error("退回用户积分失败: orderId={}", orderInfoDTO.getId(), e);
            throw new BusinessException(ErrorCode.INTEGRAL_RETURN_FAILED);
        }
    }

    /**
     * 计算需要退回的积分
     */
    private int calculatePointsToReturn(BigDecimal pointAmount) {
        String configValue = systemConfigService.getConfigValue(
                SystemConfigConstants.CONFIG_GROUP_INTEGRAL,
                SystemConfigConstants.CONFIG_KEY_DEDUCTION_RULE
        );
        try {
            DeductionDTO dto = JSON.convert(configValue, DeductionDTO.class);
            return pointAmount.multiply(BigDecimal.valueOf(dto.getPoints_per_yuan())).intValue();
        } catch (Exception e) {
            log.warn("积分规则解析失败，使用默认比例", e);
            return pointAmount.multiply(BigDecimal.valueOf(100)).intValue();
        }
    }

    /**
     * 退回积分到用户账户
     */
    private void returnPointsToUser(Long userId, int points) {
        int updated = customerMapper.addUserPoints(userId, points);
        if (updated <= 0) {
            throw new BusinessException(ErrorCode.USER_NOT_EXIST.getCode(), "用户不存在或更新失败");
        }
    }

    /**
     * 记录积分变更
     */
    private void recordIntegralChange(Long userId, int points, Long businessId) {
        int currentPoints = customerMapper.selectPointsByUserId(userId);
        IntegralRecord integralRecord = new IntegralRecord();
        integralRecord.setId(idGenerator.nextId());
        integralRecord.setUserId(userId);
        integralRecord.setPoints(points);
        integralRecord.setCurrentBalance(currentPoints);
        integralRecord.setType(IntegralType.CANCEL_ORDER_SEND_BACK.getCode());
        integralRecord.setBusinessId(String.valueOf(businessId));
        integralRecord.setBusinessType(IntegralType.BusinessType.cancel_order.name());
        integralRecord.setDescription(IntegralType.CANCEL_ORDER_SEND_BACK.getDesc());

        int inserted = integralRecordMapper.insert(integralRecord);
        if (inserted <= 0) {
            log.warn("积分记录插入失败，但不影响主流程: userId={}", userId);
        }
    }

    /**
     * 取消订单回滚库存
     */
    private void releaseInventory(OrderInfoDTO orderInfoDTO) {
        try {
            log.info("开始回滚库存: orderId={}", orderInfoDTO.getId());

            // 获取订单商品项
            List<OrderItemDTO> orderItems = orderInfoDTO.getOrderItems();

            // 合并相同SKU的数量
            Map<Long, Integer> skuNumbers = orderItems.stream()
                    .collect(Collectors.toMap(
                            item -> item.getPromotionProductId() != null ?
                                    item.getPromotionProductId() : item.getSkuId(),
                            OrderItemDTO::getSkuNumber,
                            Integer::sum
                    ));

            // 回滚数据库库存
            boolean dbRollbackSuccess = rollbackDatabaseStock(orderInfoDTO, skuNumbers);
            if (!dbRollbackSuccess) {
                log.warn("mysql库存回滚失败,orderId={}", orderInfoDTO.getId());
                throw new BusinessException(ErrorCode.STOCK_ROLLBACK_FAILED);
            }

            // 回滚Redis库存
            boolean redisRollbackSuccess = rollbackRedisStock(orderInfoDTO, skuNumbers);
            if (!redisRollbackSuccess) {
                log.warn("Redis库存回滚失败，需要人工干预: orderId={}", orderInfoDTO.getId());
                throw new BusinessException(ErrorCode.STOCK_ROLLBACK_FAILED);
            }

            log.info("库存回滚完成: orderId={}", orderInfoDTO.getId());

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("库存回滚异常: orderId={}", orderInfoDTO.getId(), e);
            throw new BusinessException(ErrorCode.STOCK_ROLLBACK_FAILED);
        }
    }

    /**
     * 回滚数据库库存
     */
    private boolean rollbackDatabaseStock(OrderInfoDTO orderInfoDTO, Map<Long, Integer> skuNumbers) {
        Long promotionId = orderInfoDTO.getPromotionId();
        int affectedRows;

        if (!Objects.equals(GeneralConstants._L1, promotionId)) {
            affectedRows = promotionProductMapper.returnMultiStock(promotionId, skuNumbers);
        } else {
            affectedRows = productSkuMapper.returnMultiStock(skuNumbers);
        }

        if (affectedRows != skuNumbers.size()) {
            log.warn("库存回滚影响行数不匹配: expected={}, actual={}", skuNumbers.size(), affectedRows);
            return false;
        }

        return true;
    }

    /**
     * 回滚Redis库存
     */
    private boolean rollbackRedisStock(OrderInfoDTO orderInfoDTO, Map<Long, Integer> skuNumbers) {
        try {
            String prefix = !Objects.equals(orderInfoDTO.getPromotionId(), GeneralConstants._L1) ?
                    RedisKeyConstants.PRODUCT_PROMOTION_STOCK :
                    RedisKeyConstants.PRODUCT_STOCK;

            return stockService.rollBackedMultiStock(skuNumbers, prefix);
        } catch (Exception e) {
            log.warn("Redis库存回滚异常", e);
            return false;
        }
    }

    /**
     * 创建退款记录
     */
    private OrderRefund createOrderRefund(OrderCancelContext context) {
        OrderInfoDTO orderInfo = context.getOrderInfoDTO();
        OrderRefund orderRefund = new OrderRefund();
        orderRefund.setId(idGenerator.nextId());
        orderRefund.setUserId(context.getUserId());
        orderRefund.setOrderId(orderInfo.getId());
        orderRefund.setOrderItemId(orderInfo.getOrderItems().stream()
                .map(item -> String.valueOf(item.getId()))
                .collect(Collectors.joining(",")));
        orderRefund.setOrderNo(orderInfo.getOrderNo());
        orderRefund.setRefundNo(generateRefundNo());
        orderRefund.setRefundType(RefundType.FULL_ORDER.getType());
        orderRefund.setRefundReason(RefundReason.OTHER.getReason());
        orderRefund.setRefundDesc(RefundReason.OTHER.getReasonDesc());
        orderRefund.setApplyRefundAmount(orderInfo.getPaymentAmount());
        orderRefund.setRefundStatus(RefundStatus.REFUNDING.getStatus());
        orderRefund.setPaymentType(orderInfo.getPaymentType());
        orderRefund.setImages("");
        orderRefund.setRemark("商品未出库，已自动退款");

        return orderRefund;
    }

    /**
     * 生成退款单号
     */
    private String generateRefundNo() {
        return "R" + System.currentTimeMillis() + RandomUtil.randomNumbers(4);
    }


    /**
     * 获取分布式锁
     */
    private boolean acquireLock(RLock lock) {
        try {
            return lock.tryLock(RedisKeyConstants.WAIT_TIME, RedisKeyConstants.LEASE_TIME, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.warn("获取分布式锁被中断", e);
            return false;
        }
    }

    /**
     * 释放分布式锁
     */
    private void releaseLock(RLock lock) {
        try {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        } catch (Exception e) {
            log.warn("释放分布式锁失败", e);
        }
    }
}
